﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SearchAssembly
{
    /// <summary>
    /// Wizard Helper Class consists of helper methods required to design and develop a Wizard based application.
    /// The architecture drawn for Wizard based application is simple and all the associated helper methods are within this class.
    /// </summary>
    /// <remarks>
    /// Its a abstract class with static methods for ease of use
    /// </remarks>
    public abstract class WizardHelper
    {
        /// <summary>
        /// This List stores all the wizard pages.
        /// Wizard pages are added as and when they are saved, meaning if the data about the poage to be restored during back/forth navigation.
        /// </summary>
        /// <remarks>
        /// Pages may not be added if the corresponding data is not saved.
        /// This ensures that the application foot-print remains thin and tidy.
        /// </remarks>
        protected static List<WizardPage> wizardPages = new List<WizardPage>();

        /// <summary>
        /// Loads the wizard page.
        /// Page is loaded with the supplied page data <paramref name="date4Page2Load"/>.
        /// </summary>
        /// <param name="currentPage">Calling page</param>
        /// <param name="typeOfPage2Load">Page type to load</param>
        /// <param name="date4Page2Load">Specific data that needs to be loaded for the page</param>
        public static void LoadPage(frmMaster currentPage, PageType typeOfPage2Load, WizardData.PageDataDataTable date4Page2Load)
        {
            frmMaster page2Load = null;
            if (wizardPages.Exists(page => page.typeOfPage == typeOfPage2Load))
            {
                WizardPage pageFound = wizardPages.Find(page => page.typeOfPage == typeOfPage2Load);

                // ========================================
                // Section for creating object of type Page2Load
                // ========================================                
                switch (pageFound.typeOfPage)
                {
                    case PageType.Welcome:
                        page2Load = new frmWelcome();
                        break;
                    case PageType.AssemblySearch:
                        page2Load = new frmSearchAssembly();
                        break;                    
                }

                if (page2Load != null)
                    page2Load.pageData = pageFound.pageData;
                else
                    throw new Exception("Page not of correct type.");
                // ========================================               
            }
            else
            {
                switch (typeOfPage2Load)
                {
                    case PageType.Welcome:
                        page2Load = new frmWelcome();
                        break;
                    case PageType.AssemblySearch:
                        page2Load = new frmSearchAssembly();
                        break;                    
                }

                page2Load.pageData = date4Page2Load;
            }

            currentPage.ShowPage(page2Load);
        }

        /// <summary>
        /// Loads the wizard page.
        /// If page exists in wizardPages then the corresponding page data is also loaded.
        /// </summary>
        /// <param name="currentPage">Calling page</param>
        /// <param name="typeOfPage2Load">Page type to load</param>        
        public static void LoadPage(frmMaster currentPage, PageType typeOfPage2Load)
        {
            LoadPage(currentPage, typeOfPage2Load, null);
        }

        /// <summary>
        /// Saves the page along with its associated data for future reference.
        /// </summary>
        /// <param name="currentPage">Calling page</param>
        public static void SavePage(WizardPage currentPage)
        {
            int pageIndex = wizardPages.FindIndex(page => page.typeOfPage == currentPage.typeOfPage);

            if (pageIndex > -1)
            {
                wizardPages.RemoveAt(pageIndex);
            }

            wizardPages.Add(currentPage);
        }

        /// <summary>
        /// Returns the data associated with the type of the page.
        /// </summary>
        /// <param name="typeOfPage">Type of page for whom the data to be returned</param>
        /// <returns>Data associated with the type of page else returns null</returns>
        public static WizardData.PageDataDataTable GetData(PageType typeOfPage)
        {
            if (wizardPages.Exists(page => page.typeOfPage == typeOfPage))
            {
                WizardPage pageFound = wizardPages.Find(page => page.typeOfPage == typeOfPage);

                return pageFound.pageData;
            }

            return null;
        }

        /// <summary>
        /// Displays a wizard page as dialog.
        /// </summary>
        /// <param name="currentPage">Calling page</param>
        /// <param name="DialogPage">Page to be loaded as dialog</param>
        /// <param name="PageData">Any specific data to be passed while loading the page as dialog</param>
        /// <param name="Modal">Display page as modal</param>
        public static void ShowDialog(frmMaster currentPage, DialogType DialogPage, System.Data.DataTable PageData, bool Modal)
        {
            frmMaster dialog2Load = new frmMaster();
            switch (DialogPage)
            {
                default:
                    dialog2Load = null;
                    break;
            }

            currentPage.ShowDialog(dialog2Load, PageData, Modal);
        }
    }

    /// <summary>
    /// Custom structure compositing Wizard Page
    /// </summary>
    public struct WizardPage
    {
        /// <summary>
        /// Type of page, to be chosen from the <typeparamref name="PageType"/> enum.
        /// </summary>
        public PageType typeOfPage;

        /// <summary>
        /// Associated page data. Will be null by default.
        /// </summary>
        public WizardData.PageDataDataTable pageData;
    };

    /// <summary>
    /// Page type enum for storing type of pages application wants to use.
    /// </summary>
    public enum PageType
    {
        /// <summary>
        /// Welcome page
        /// </summary>
        Welcome = 1,
        /// <summary>
        /// Assembly Search Page
        /// </summary>
        AssemblySearch = 2        
    }

    /// <summary>
    ///  Dialog type enum for storing types of dialog application wants to use.
    /// </summary>
    public enum DialogType
    {
        /// <summary>
        /// LetMeChoose Dialog Page
        /// </summary>
        LetMeChoose = 1
    }
}